// <copyright file="XslTransformForm.cs" company="Sinclair Community College">
// Copyright (c) Sinclair Community College. All rights reserved.
// </copyright>

namespace SinclairCC.AppVSuite.DuplicateRootDetector
{
    using System;
    using System.Collections.Generic;
    using System.Windows.Forms;

    /// <summary>
    /// This class defines a form that allows the user to transform the data gathered
    /// by the application into an XML, HTML or text document.
    /// </summary>
    internal partial class XslTransformForm : Form
    {
        /// <summary>
        /// The path of the XML document to be transformed.
        /// </summary>
        private string xmlFilePath;

        /// <summary>
        /// Initializes a new instance of the XslTransformForm class.
        /// </summary>
        /// <param name="xmlFilePath">
        /// The path of the XML document to be transformed.
        /// </param>
        public XslTransformForm(string xmlFilePath)
        {
            this.InitializeComponent();

            this.xmlFilePath = xmlFilePath;

            Shared.PrepareStylesheetRepository();

            /*DuplicateRootDetector.Properties.Settings.Default.lastStylesheetPath = filePath;*/

            this.textOutputFilePath.Text = DuplicateRootDetector.Properties.Settings.Default.lastHtmlOutputPath;
            this.textXslFilePath.Text = DuplicateRootDetector.Properties.Settings.Default.lastStylesheetPath;
        }



        /// <summary>
        /// Handles the Click event for the Create File button.
        /// </summary>
        /// <param name="sender">
        /// The button being clicked.
        /// </param>
        /// <param name="e">
        /// Data specific to this event.
        /// </param>
        private void ClickCreateFileButton(object sender, EventArgs e)
        {
            this.TransformXML(this.textOutputFilePath.Text);
            MessageBox.Show(this, "File creation complete.", "Duplicate Root Detector", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
            this.Close();
        }

        /// <summary>
        /// Transforms the XML document to the specified output file, using the selected spreadsheet.
        /// </summary>
        /// <param name="outputFilePath">
        /// The path of the output file to be created.
        /// </param>
        private void TransformXML(string outputFilePath)
        {
            System.Xml.Xsl.XslCompiledTransform transform = new System.Xml.Xsl.XslCompiledTransform(false);
            transform.Load(this.textXslFilePath.Text);

            System.Xml.XmlTextWriter results = new System.Xml.XmlTextWriter(outputFilePath, System.Text.Encoding.Unicode);
            System.Xml.XmlTextReader input = new System.Xml.XmlTextReader(this.xmlFilePath);
            transform.Transform(input, results);
            input.Close();
            results.Close();
        }

        /// <summary>
        /// Presents an OpenFileDialog, using a list of extensions to build the filter.
        /// </summary>
        /// <param name="extensionList">
        /// The list of extensions to show in the dialog's filter.
        /// </param>
        /// <param name="targetTextBox">
        /// The text box that will receive the path of the selected file if the user
        /// selects OK in the open file dialog.
        /// </param>
        /// <param name="checkFileExists">
        /// Specifies whether to check that the file specified by the user exists.
        /// </param>
        /// <returns>
        /// True if the user clicks OK at the file dialog; otherwise, false.
        /// </returns>
        /// <remarks>
        /// If the user selects a file and clicks OK, the selected file path is placed in the
        /// specified TextBox control.
        /// </remarks>
        private bool BrowseForFile(List<string> extensionList, TextBox targetTextBox, bool checkFileExists)
        {
            return this.BrowseForFile(extensionList, targetTextBox, checkFileExists, null);
        }

        /// <summary>
        /// Presents an OpenFileDialog, using a list of extensions to build the filter.
        /// </summary>
        /// <param name="extensionList">
        /// The list of extensions to show in the dialog's filter.
        /// </param>
        /// <param name="targetTextBox">
        /// The text box that will receive the path of the selected file if the user
        /// selects OK in the open file dialog.
        /// </param>
        /// <param name="checkFileExists">
        /// Specifies whether to check that the file specified by the user exists.
        /// </param>
        /// <param name="initialDirectory">
        /// The directory in which the file dialog should start when it opens.
        /// </param>
        /// <returns>
        /// True if the user clicks OK at the file dialog; otherwise, false.
        /// </returns>
        /// <remarks>
        /// If the user selects a file and clicks OK, the selected file path is placed in the
        /// specified TextBox control.
        /// </remarks>
        private bool BrowseForFile(List<string> extensionList, TextBox targetTextBox, bool checkFileExists, string initialDirectory)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.CheckFileExists = checkFileExists;

            // Build the filter for the file dialog.
            PatrickSeymour.FileDialogFilterBuilder filterBuilder = new PatrickSeymour.FileDialogFilterBuilder();
            foreach (string ext in extensionList)
            {
                filterBuilder.AddExtension(ext);
            }

            filterBuilder.ShowExtensions = true;
            ofd.Filter = filterBuilder.FilterString;

            if (initialDirectory != null)
            {
                ofd.InitialDirectory = initialDirectory;
            }

            if (ofd.ShowDialog(this) == DialogResult.OK)
            {
                targetTextBox.Text = ofd.FileName;
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Presents an OpenFileDialog, using a list of extensions to build the filter.
        /// </summary>
        /// <param name="extension">
        /// The extension to show in the dialog's filter.
        /// </param>
        /// <param name="targetTextBox">
        /// The text box that will receive the path of the selected file if the user
        /// selects OK in the open file dialog.
        /// </param>
        /// <param name="checkFileExists">
        /// Specifies whether to check that the file specified by the user exists.
        /// </param>
        /// <param name="initialDirectory">
        /// The directory in which the file dialog should start when it opens.
        /// </param>
        /// <returns>
        /// True if the user clicks OK at the file dialog; otherwise, false.
        /// </returns>
        /// <remarks>
        /// If the user selects a file and clicks OK, the selected file path is placed in the
        /// specified TextBox control.
        /// </remarks>
        private bool BrowseForFile(string extension, TextBox targetTextBox, bool checkFileExists, string initialDirectory)
        {
            return this.BrowseForFile(new List<string>(new string[] { extension }), targetTextBox, checkFileExists, initialDirectory);
        }

        /// <summary>
        /// Handles the Click event for the Browse button for the XSL file path.
        /// </summary>
        /// <param name="sender">
        /// The source of the event.
        /// </param>
        /// <param name="e">
        /// Data specific to the event.
        /// </param>
        private void ClickBrowseForXslFileButton(object sender, EventArgs e)
        {
            if (this.BrowseForFile("xsl", this.textXslFilePath, true, Shared.StylesheetRepositoryFolderPath))
            {
                DuplicateRootDetector.Properties.Settings.Default.lastStylesheetPath = this.textXslFilePath.Text;
                DuplicateRootDetector.Properties.Settings.Default.Save();
            }
        }

        /// <summary>
        /// Handles the Click event for the Browse button for the output file path.
        /// </summary>
        /// <param name="sender">
        /// The source of the event.
        /// </param>
        /// <param name="e">
        /// Data specific to the event.
        /// </param>
        private void ClickBrowseForOutputFileButton(object sender, EventArgs e)
        {
            if (this.BrowseForFile(new List<string>(new string[] { "html", "xsl", "xml", "htm" }), this.textOutputFilePath, false))
            {
                DuplicateRootDetector.Properties.Settings.Default.lastHtmlOutputPath = this.textOutputFilePath.Text;
                DuplicateRootDetector.Properties.Settings.Default.Save();
            }
        }

        /// <summary>
        /// Handles the TextChanged event for the XSL file path text box.
        /// </summary>
        /// <param name="sender">
        /// The source of the event.
        /// </param>
        /// <param name="e">
        /// Data specific to the event.
        /// </param>
        private void StylesheetPathChanged(object sender, EventArgs e)
        {
            this.ToggleCreateButton();
        }

        /// <summary>
        /// Handles the TextChanged event for the output file path text box.
        /// </summary>
        /// <param name="sender">
        /// The source of the event.
        /// </param>
        /// <param name="e">
        /// Data specific to the event.
        /// </param>
        private void OutputPathChanged(object sender, EventArgs e)
        {
            this.ToggleCreateButton();
        }

        /// <summary>
        /// Sets the Enabled property for the Create File button.
        /// </summary>
        private void ToggleCreateButton()
        {
            string outputFilePath = this.textOutputFilePath.Text.Trim();
            string stylesheetFilePath = this.textXslFilePath.Text.Trim();

            //// TODO: Check whether the output file path is valid.

            this.createFileButton.Enabled = System.IO.File.Exists(stylesheetFilePath);
        }
    }
}